﻿using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Linq;
using System.Collections.Generic;
using ToolBoxPro;

/// <summary>
/// Summary description for Campaign
/// </summary>

namespace LinqObj
{
    public partial class Campaign
    {
        private static ToolboxDataContext _context = new ToolboxDataContext();


        public static IDictionary<int, string> CampaignStatusLookups
        {
            get
            {
                if (campaignStatusLookups != null)
                    return campaignStatusLookups;

                return (campaignStatusLookups = initCampaignLookups());

            }       
        }

        private static IDictionary<int, string> campaignStatusLookups;

        //private int agentId;
        //private int useID;
        //private int propertyID;
        //private int campaignID;

        //public int AgentID { get { return this.agentId; } set { this.agentId = value; } }
        //public int UserID { get { return this.useID; } set { this.useID = value; } }
        //public int PropertyID { get { return this.propertyID; } set { this.propertyID = value; } }
        //public int CampaignID { get { return this.campaignID; } set { this.campaignID = value; } }

        public const string STATUS_ARCHIVED = Property.STATUS_ARCHIVED;
        public const string STATUS_INACTIVE = Property.STATUS_INACTIVE;
        public const string STATUS_CURRENT = Property.STATUS_ACTIVE;

        public string _CampaignStatus
        {
            get
            {
                return CampaignStatusLookups[this.campaign_status];
            }
        }

        partial void OnCreated()
        {
            campaignStatusLookups = (from a in _context.GetTable<Campaign_Status>()
                                     select a).ToDictionary(id => id.status_id, status => status.status);

        }

        private static IDictionary<int, string> initCampaignLookups()
        {
            return (from a in _context.GetTable<Campaign_Status>()
             select a).ToDictionary(id => id.status_id, status => status.status);
        }

        /*
         * Get a property attached to the property. There should be only one inactive/active campaign attached. 
         */
        public static Campaign GetCurrentCampaignByProperty(int propertyID)
        {

            if (Campaign.CampaignStatusLookups == null)
            {
                campaignStatusLookups = (from a in _context.GetTable<Campaign_Status>()
                                         select a).ToDictionary(id => id.status_id, status => status.status);
            }
            Campaign campaign = (from _campaign in _context.GetTable<Campaign>()
                                 where _campaign.property_id == propertyID && _campaign.campaign_status ==
                                    FormContract.FindKey(Campaign.CampaignStatusLookups, Campaign.STATUS_CURRENT)
                                 select _campaign).SingleOrDefault();
            if (campaign == null)
                campaign = (from _campaign in _context.GetTable<Campaign>()
                            where _campaign.property_id == propertyID && _campaign.campaign_status ==
                                    FormContract.FindKey(Campaign.CampaignStatusLookups, Campaign.STATUS_INACTIVE)
                            select _campaign).SingleOrDefault();
            return campaign;
        }

        public static void AddCampaign(Campaign campaign)
        {
            campaign.created = DateTime.Now;
            campaign.SetCampaignStatus(Campaign.STATUS_INACTIVE);
            _context.GetTable<Campaign>().InsertOnSubmit(campaign);
        }

        public void SetCampaignStatus(string strCampaignStatus)
        {
            int? key = FormContract.FindKey(CampaignStatusLookups, strCampaignStatus);
            if (!key.HasValue)
                throw new Exception("the value is not found in the AllocatedStatusLookups");
            else
                SetCampaignStatus(key.Value);
        }

        public void SetCampaignStatus(int _campaignStatus)
        {
            if (_campaignStatus == this.campaign_status || _campaignStatus <= 0)
                return;

            // Check if it changes Archived
            // ! Only one inactive/active campaign for a property

            this.Campaign_Status1 = (from a in _context.GetTable<Campaign_Status>()
                                     where a.status_id == _campaignStatus
                                     select a).SingleOrDefault();
        }

        public static List<Campaign> GetAllCampaigns(int propertyID)
        {
            return (from _campaigns in _context.GetTable<Campaign>()
                    where _campaigns.property_id == propertyID
                    select _campaigns).ToList();
        }


        private void addOrder(Order order)
        {
            if (order.order_id <= 0)
            {
                _context.GetTable<Order>().InsertOnSubmit(order);
            }
        }

        public static void SubmitChanges()
        {
            try
            {
                _context.SubmitChanges();
            }
            catch (Exception ex)
            {
                _context.ChangeConflicts.Clear();
                _context.SubmitChanges();
            }
        }


        private void updateOrder(int orderID, Order order)
        {
            Order _order = (from _a in _context.GetTable<Order>()
                            where _a.order_id == orderID
                            select _a).SingleOrDefault();

            _order.order_date = order.order_date;
            _order.due_date = order.due_date;
            _order.campaign_id = this.campaign_id;
        }

        public void SaveOrders(List<Order> orderList)
        {
            IsInDB check = new IsInDB();
            //_context.Refresh(System.Data.Linq.RefreshMode.KeepCurrentValues);
            List<Order> existings = Order.LoadOrderList(this.property_id, this._CampaignStatus);
            if (orderList != null)
            {
                foreach (Order _order in orderList)
                {
                    if (existings == null)
                        break;
                    if (!existings.Contains(_order, check))
                    {
                        addOrder(_order);
                    }
                    else
                    {
                        for (int i = 0; i < existings.Count; i++)
                        {
                            if (existings[i].service_id == _order.service_id)
                            {
                                updateOrder(existings[i].order_id, _order);
                            }
                        }
                    }
                }
            }

            List<int> toDelete = new List<int>();

            if (existings != null)
            {
                if (orderList != null && orderList.Count > 0)
                {
                    foreach (Order exOrder in existings)
                    {
                        if (!orderList.Contains(exOrder, check))
                        {
                            toDelete.Add(exOrder.order_id);
                        }
                    }
                }
                else
                {
                    foreach (Order a in existings)
                    {
                        toDelete.Add(a.order_id);
                    }
                }
            }

            deleteOrders(toDelete);
            try
            {
                _context.SubmitChanges();
            }
            catch (Exception ex)
            {
                _context.ChangeConflicts.Clear();
                _context.SubmitChanges();
            }
        }

        public Order getOrder(List<Order> orders, int serviceID)
        {
            return orders.First(a => a.service_id == serviceID);
        }


        public void deleteOrders(List<int> toDelete)
        {
            var collect = from _orders in _context.GetTable<Order>()
                          where toDelete.Contains(_orders.order_id)
                          select _orders;
            _context.GetTable<Order>().DeleteAllOnSubmit(collect);
        }

        public static void StatusToSent(int orderID)
        {
            Order order = (from a in _context.GetTable<Order>()
                           where a.order_id == orderID
                           select a).SingleOrDefault();
            try
            {
                if (order != null)
                {
                    order.order_status = Order.STATUS_ORDERED;
                    order.email_sent = true;
                    _context.SubmitChanges();
                }
            }
            catch (Exception ex)
            {
                _context.ChangeConflicts.Clear();
                _context.SubmitChanges();
            }
        }

        public static string GetCampaignStatus(int propertyID)
        {
            return (from a in _context.GetTable<Campaign>()
                    where a.property_id == propertyID && a._CampaignStatus == Campaign.STATUS_CURRENT
                    select a._CampaignStatus).SingleOrDefault();
        }

        public static List<Campaign_Status> LoadCampaignStatusList()
        {
            return (from a in _context.GetTable<Campaign_Status>()
                    select a).ToList();
        }

        public static List<Campaign_Status> LoadCampaignStatusList(string excludeStatus)
        {
            if (excludeStatus == null)
                return (from a in _context.GetTable<Campaign_Status>()
                        orderby a.status_id
                        select a).ToList();
            return (from a in _context.GetTable<Campaign_Status>()
                    where a.status.ToLower() != excludeStatus.ToLower()
                    orderby a.status_id
                    select a).ToList();
        }

        public List<Order> GetOrders()
        {
            return (from a in _context.GetTable<Order>()
                    where a.campaign_id == this.campaign_id
                    select a).ToList();
        }

        public static Campaign GetCampaign(int campaignID)
        {
            return (from a in _context.GetTable<Campaign>()
                    where a.campaign_id == campaignID
                    select a).SingleOrDefault();
        }

        //    public static void setCampaignForProperty(IDbConnection conn, Campaign campaign)
        //    {

        //        string sql_script =
        //                                @"select campaign_id from campaign where property_id =@propertyID and campaign_status <> @historiyKey";

        //        int campaignID = 0;
        //        IDbTransaction trans = conn.BeginTransaction();
        //        try
        //        {

        //            IDbCommand cmd = conn.CreateCommand();
        //            cmd.Transaction = trans;
        //            cmd.CommandText = sql_script;

        //            IDbDataParameter param = cmd.CreateParameter();
        //            param.ParameterName = "@propertyID";
        //            param.DbType = DbType.Int32;
        //            param.Value = campaign.PropertyID;
        //            cmd.Parameters.Add(param);

        //            param = cmd.CreateParameter();
        //            param.ParameterName = "@historiyKey";
        //            param.DbType = DbType.String;
        //            param.Value = Campaign.HISTORIC;
        //            cmd.Parameters.Add(param);
        //            Object dbResult = cmd.ExecuteScalar();



        //            if (dbResult != null)
        //            {
        //                campaignID = Convert.ToInt32(dbResult.ToString());
        //                campaign.CampaignID = campaignID;
        //                trans.Commit();
        //            }
        //            else
        //            {
        //                sql_script =
        //                                   @"insert into campaign(property_id, agent_id, user_id)
        //                                values(@propertyID2, @agentID, @userID);";                
        //                cmd.CommandText = sql_script;
        //                param = cmd.CreateParameter();
        //                param.ParameterName = "@propertyID2";
        //                param.DbType = DbType.Int32;
        //                param.Value = campaign.PropertyID;
        //                cmd.Parameters.Add(param);

        //                param = cmd.CreateParameter();
        //                param.ParameterName = "@agentID";
        //                param.DbType = DbType.Int32;
        //                param.Value = campaign.AgentID;
        //                cmd.Parameters.Add(param);

        //                param = cmd.CreateParameter();
        //                param.DbType = DbType.Int32;
        //                param.ParameterName = "@userID";
        //                param.Value = campaign.UserID;
        //                cmd.Parameters.Add(param);

        //                cmd.ExecuteNonQuery();

        //                cmd.CommandText = @"select IDENT_CURRENT('campaign') as campaign_id";

        //                campaignID = Convert.ToInt32(cmd.ExecuteScalar().ToString());
        //                campaign.CampaignID = campaignID;
        //                trans.Commit();
        //            }
        //        }

        //        catch (Exception error)
        //        {
        //            trans.Rollback();
        //            throw (error);
        //        }
        //    }
    }

    public class IsInDB : IEqualityComparer<Order>
    {
        public bool Equals(Order _order1, Order _order2)
        {
            //@serviceID and campaign_id = @campaignID and order_status<>@orderStatus
            if (_order1.campaign_id == _order2.campaign_id &&
                    _order1.service_id == _order2.service_id)
                return true;
            return false;
        }

        public int GetHashCode(Order obj)
        {
            return obj.GetHashCode();
        }
    }
}